import {DataRouter} from "../../frame/dataSource/DataRouter";
import {
    AffixData,
    AttackMonsterData,
    AttributeEnum,
    CombinationData,
    ConditionData,
    DifficultData,
    DifficultMode,
    HandBookData,
    IconData,
    PlayerAttribute,
    UnitAttribute,
    UnitData,
    UnitType,
    WeightIDData
} from "../../frame/dataSource/DataModel";
import Configer from "../../frame/apiModel/config/Configer";
import {AttrSetting, ConfigKey} from "../../constant/ConfigConstant";
import MathUtil from "../../frame/codeAdapter/MathUtil";
import {PlayerModel} from "../../frame/apiModel/adapterModel/model4/PlayerModel";
import {UnitModel} from "../../frame/apiModel/adapterModel/model3/UnitModel";
import {AbilityJson} from "../../frame/apiModel/model/StoreJson";
import {CodeUtil} from "../../frame/codeAdapter/CodeUtil";
import {Logger} from "../../frame/apiModel/config/Logger";
import {ItemModel} from "../../frame/apiModel/adapterModel/model3/ItemModel";
import {Attrs, CaluType, ColorStr, CombinationUIInfo, CombitionRet, MaterialInfo} from "../../type/Type";
import {ItemDataKey} from "../../frame/dataSource/DataSource";
import {ItemInfo} from "../../../gui/interface/GuiInterface";
import {PositionConfig, UIConfigKey} from "../../constant/UIConfig";
import {Util} from "../Util";

export class DataRouterUtil {

    static getNewAttackByWaveAndDifficult(attack: number, wave: number, waveStrengthen: number, difficultData: DifficultData) {
        let ret = attack;
        if (difficultData) {
            const attackRadix = difficultData.attackRadix;
            ret =  attack * attackRadix;
        }
        if (!CodeUtil.isNullOrZero(waveStrengthen) && wave > 0) {
            ret =  attack * wave * waveStrengthen;
        }
        return ret;
    }
    static getNewLifeByWaveAndDifficult(life: number, wave: number, waveStrengthen: number, difficultData: DifficultData) {
        let ret = life;
        if (difficultData) {
            const lifeRadix = difficultData.lifeRadix;
            ret =  life * lifeRadix;
        }
        if (!CodeUtil.isNullOrZero(waveStrengthen) && wave > 0) {
            ret =  life * wave * waveStrengthen;
        }
        return ret
    }
    static getNewDefenseByWaveAndDifficult(defense: number, wave: number, waveStrengthen: number, difficultData: DifficultData) {
        if (difficultData) {
            const defenseRadix = difficultData.defenseRadix;
            return defense * defenseRadix;
        }
        return defense;
    }
    static getNewValueByPlayerNum(oldValue: number, playerNum: number, playerNumAddRadix: string) {
        if (playerNumAddRadix) {
            const radixs = CodeUtil.getArrBySplit(playerNumAddRadix);
            const radix = DataRouterUtil.getNumByArr(radixs, playerNum - 1);
            if (!CodeUtil.isNullOrZero(radix)) {
                const newValue = oldValue * radix;
                return newValue
            } else {
                const len = radixs.length;
                const tempRadix = DataRouterUtil.getNumByArr(radixs, len - 1);
                if (!CodeUtil.isNullOrZero(tempRadix)) {
                    const newValue = oldValue * tempRadix;
                    return newValue
                }
            }
        }
        return oldValue;
    }
    static getAttackMonsterDatasByMode(mode: DifficultMode) {
        const datas = DataRouter.getAttackMonsterDatas();
        let ret: AttackMonsterData[] = [];
        for (let i = 0; i < datas.length; i++) {
            const data = datas[i];
            if (data.mode) {
                if (data.mode === mode) {
                    ret.push(data);
                }
            } else {
                ret.push(data);
            }
        }
        return ret;
    }
    static setMonsterAttrByWaveAndDifficuteAndPlayerNum(attrs: Attrs, wave: number, difficultData: DifficultData, playerNum: number = 1, waveAttackStrengthen: number = 0, waveLifeStrengthen: number = 0, playerNumAddRadixAttack: string, playerNumAddRadixLife: string) {
        const unitAttr = attrs.unitAttr;
        const life = unitAttr[AttributeEnum.maxLife];
        const attack = unitAttr[AttributeEnum.attack];
        const defense = unitAttr[AttributeEnum.defense];
        let newAttack = DataRouterUtil.getNewAttackByWaveAndDifficult(attack, wave - 1, waveAttackStrengthen, difficultData);
        // newAttack = DataRouterUtil.getNewValueByPlayerNum(newAttack, playerNum, playerNumAddRadixAttack);
        let newLife = DataRouterUtil.getNewLifeByWaveAndDifficult(life, wave - 1, waveLifeStrengthen, difficultData);
        newLife = DataRouterUtil.getNewValueByPlayerNum(newLife, playerNum, playerNumAddRadixLife);
        // let newDefense = DataRouterUtil.getNewDefenseByWaveAndDifficult(defense, wave - 1, difficult);
        // newDefense = DataRouterUtil.getNewValueByPlayerNum(newDefense, playerNum);
        unitAttr[AttributeEnum.maxLife] = newLife
        unitAttr[AttributeEnum.maxLife] = newLife
        unitAttr[AttributeEnum.attack] = newAttack
        // SetUnitState(unit, ConvertUnitState(0x20), newDefense);
    }

    static setMonsterAttrByBoss(unit: UnitModel, number: number) {
        const life = unit.maxLife;

        const diffRadix: number[] = Configer.getConfig(ConfigKey.diffRadixByBossNum);
        let radix: number = diffRadix[number - 1];
        if (radix) {
            const strId = unit.strId;
            const unitData = DataRouter.getUnitDataByUnitId(strId);
            if (unitData) {
                const name = unitData?.Name;
                Logger.toastProduct(`Boss-${name}: 加强！`)
            } else {
                Logger.toastProduct(`无法加强一个不存在的单位！${strId}`)
                return;
            }
        } else {
            return;
        }
        let newLife = life * radix;
        // let newDefense = DataRouterUtil.getNewDefenseByWaveAndDifficult(defense, wave - 1, difficult);
        // newDefense = DataRouterUtil.getNewValueByPlayerNum(newDefense, playerNum);
        unit.maxLife = newLife;
        unit.life = newLife;
        // SetUnitState(unit, ConvertUnitState(0x20), newDefense);
    }
    // 遍历角色已有技能中目标技能家族的技能
    static getUnitAbilityIdByFamilyId(unit: UnitModel, familyId: string): AbilityJson {
        let ret: AbilityJson = { id: undefined, lv: -1, cd: 0 };
        const abilityIdArr = DataRouter.getAbilityIdsByFamilyId(familyId);
        if (abilityIdArr) {
            for (let i = 0; i < abilityIdArr.length; i++) {
                const abilityFamilyHotKey = abilityIdArr[i];
                if (abilityFamilyHotKey) {
                    const keys = Object.keys(abilityFamilyHotKey);
                    for (const key of keys) {
                        const abilityId = abilityFamilyHotKey[key];
                        if (unit.hasAbility(abilityId)) {
                            ret.id = abilityId;
                            ret.lv = i;
                            return ret;
                        }
                    }
                }
            }
        } else {
            Logger.toastError(`目标技能家族中不存在技能 ${familyId}`)
        }
        return ret;
    }
    static getNextAbilityIdByFamilyId(abilityId: string, hotKey: string): string {
        const abilityData = DataRouter.getAbilityDataById(abilityId);
        if (abilityData) {
        } else {
            Logger.toastError(`不要妄图通过一个不存在的技能 ${abilityId} 来获取下一个级别的技能`)
            return;
        }
        const familyId = abilityData.family_tpye;
        const familyLevel = abilityData.family_level;
        const abilityIdArr = DataRouter.getAbilityIdsByFamilyId(familyId);
        if (abilityIdArr) {
        } else {
            Logger.toastError(`目标技能家族中不存在技能 ${familyId}`)
            return ;
        }
        const nextFamilyLevel = familyLevel + 1;
        const nextAbilityFamilyHotKey = abilityIdArr[nextFamilyLevel];
        if (nextAbilityFamilyHotKey) {
        } else {
            return;
        }
        const nextAbilityId = nextAbilityFamilyHotKey[hotKey];
        if (nextAbilityId) {
            return nextAbilityId;
        } else {
            const defAbilityId = nextAbilityFamilyHotKey.def;
            return defAbilityId;
        }
    }
    static getNextItemIdByFamilyId(player: PlayerModel, itemId: string, bAdd: 0 | 1): string {
        const itemData = DataRouter.getItemDataByItemId(itemId);
        if (itemData) {
        } else {
            Logger.toastError(`不要妄图通过一个不存在的物品 ${itemId} 来获取下一个级别的物品`)
            return;
        }
        const familyId = itemData.family_tpye;
        const familyLevel = itemData.family_level;

        if (familyLevel && familyLevel >= 0) {
        } else {
            Logger.toastProduct(`目标物品不能升级`, player)
            return ;
        }

        const itemIdsArr = DataRouter.getItemIdsByFamilyId(familyId);
        if (itemIdsArr) {
        } else {
            Logger.toastError(`目标装备家族中不存在对应装备 ${familyId}`)
            return ;
        }
        let nextFamilyLevel: number;
        if (!CodeUtil.isNullOrZero(bAdd)) {
            nextFamilyLevel = familyLevel + 1;
        } else {
            nextFamilyLevel = familyLevel - 1;
        }
        const nextItemId = itemIdsArr[nextFamilyLevel];
        if (nextItemId) {
            return nextItemId;
        }
    }
    static getFirstUnitIdByFamilyId(familyId: string): string {
        const maxUnitFamilyNum = Configer.getConfig(ConfigKey.maxUnitFamily);
        const unitIds = DataRouter.getUnitIdsByFamilyId(familyId);
        let firstUnitId;
        let nextFamilyLevel = -1;
        if (unitIds) {
            for (let i = 0; i < maxUnitFamilyNum; i++) {
                nextFamilyLevel = nextFamilyLevel + 1;
                const tempNextUnitId = unitIds[nextFamilyLevel];
                if (tempNextUnitId) {
                    firstUnitId = tempNextUnitId;
                    break;
                }
            }
        }
        return firstUnitId;
    }
    static getNextUnitIdByFamilyId(unitId: string, num: number): string {
        const unitData = DataRouter.getUnitDataByUnitId(unitId);
        if (unitData) {
        } else {
            return;
        }
        const familyId = unitData.family_tpye;
        const familyLevel = unitData.family_level;
        const unitIds = DataRouter.getUnitIdsByFamilyId(familyId);
        if (unitIds) {
        } else {
            Logger.toastError(`目标单位家族中不存在单位 ${familyId}`)
            return;
        }
        let nextUnitId;
        let nextFamilyLevel = familyLevel;
        for (let i = 0; i < num; i++) {
            nextFamilyLevel = nextFamilyLevel + 1;
            const tempNextUnitId = unitIds[nextFamilyLevel];
            if (tempNextUnitId) {
                nextUnitId = tempNextUnitId;
            } else {
                break;
            }
        }
        return nextUnitId;
    }
    // 必须同步
    static getAffixByGroupId(groupId: string, num: number): string[] {
        const affixDatas = DataRouter.getAffixDatasByGroupID(groupId);
        const rets: string[] = [];

        if (!CodeUtil.isNullOrZero(num)) {
        } else {
            return rets;
        }

        if (affixDatas) {
            for (let numIndex = 0; numIndex < num; numIndex ++) {
                const pool: AffixData[] = [];
                let sumProbability = 0;
                for (let i = affixDatas.length - 1; i >= 0; i--) {
                    const group = affixDatas[i];
                    const id = group.id;
                    const index = rets.indexOf(id);
                    if (index >= 0) {
                        continue;
                    }
                    const probability = group.probability;
                    // const conditionIds = affixData.condition;
                    // const conditionArr = CodeUtil.getArrBySplit(conditionIds);
                    // if (conditionIds) {
                    //     Util.loggerInDev(`掉落条件：${conditionIds}`, LogType.dropDev);
                    // }
                    // const ret = this.checkConditions(conditionArr, '', player);
                    // const bCheck = ret.success;
                    const bCheck = true;
                    if (bCheck) {
                        sumProbability = sumProbability + probability;
                        pool.push(group);
                    }
                    // else {
                    //     Util.loggerInDev(`词缀：${group.id} 因不满足条件无法掉落`, LogType.goodDev);
                    // }
                }
                let random = MathUtil.random(0, sumProbability * 100) / 100;
                const endRandom = MathUtil.toFixed(random, 2);
                Logger.toastSys(`总几率：${sumProbability}`)
                let retGroup: AffixData;
                for (let i = pool.length - 1; i >= 0; i--) {
                    const item = pool[i];
                    const probability = item.probability;
                    sumProbability = sumProbability - probability;
                    if (sumProbability <= endRandom) {
                        retGroup = item;
                        break;
                    }
                }
                if (retGroup) {
                    rets.push(retGroup.id);
                } else {
                    // Logger.toastError(`词缀组 ${groupId} 无法获取词缀`);
                }
            }
        }
        return rets;
    }
    static getAbilityIdByFamilyIdHotKey(familyId: string, hotKey: string = 'def'): string {
        const abilityIds = DataRouter.getAbilityIdsByFamilyId(familyId);
        const familyLevel = 0;
        if (abilityIds) {
        } else {
            Logger.toastError(`目标技能家族中不存在技能 ${familyId}`);
            return;
        }
        const abilityFamilyHotKey = abilityIds[familyLevel];
        if (abilityFamilyHotKey) {
        } else {
            Logger.toastError(`目标技能家族 ${familyId} 中 ${familyLevel} 级不存在技能`);
            return;
        }
        const abilityId = abilityFamilyHotKey[hotKey];
        if (abilityId) {
            return abilityId;
        } else {
            const defAbilityId = abilityFamilyHotKey.def;
            return defAbilityId;
        }
    }

    static getIconUrlByIconData(iconData: IconData): string {
        const iconPath = iconData?.iconPath;
        if (iconPath) {
            const icon = DataRouter.getResourceDataByResourceId(iconPath)?.src;
            return icon;
        }
        return iconData?.Art;
    }

    static getConditionDataMapByTaskId(taskId: string) {
        const taskData = DataRouter.getTaskDataByTaskId(taskId);
        if (taskData) {
        } else {
            Logger.toastError(`判断任务完成条件时 没有对应任务信息 ${taskId}`)
            return [];
        }
        const conditionStrs = taskData.condition;
        const conditionArr = CodeUtil.getArrBySplit(conditionStrs);
        const conditionDatas: ConditionData[][] = [];
        for (let i = 0; i < conditionArr.length; i++) {
            const conditionId = conditionArr[i];
            const conditionData = DataRouter.getConditionDataByConditionId(conditionId);
            if (conditionData) {
                const conditionDataEle: ConditionData[] = conditionData;
                conditionDatas.push(conditionDataEle);
            }
        }
        return conditionDatas;
    }
    // 返回ture代表不是特殊单位
    static checkUnitUseAttr (unit: UnitModel | void) {
        if (unit) {
        } else {
            return false;
        }
        const isValidUnit = unit.isAlive();
        if (isValidUnit) {
        } else {
            return false;
        }
        const strId = unit.strId;
        const unitData = DataRouter.getUnitDataByUnitId(strId);
        // if (unit.invulnerable) {
        //     return false;
        // }
        if (unitData) {
            const useAttr = unitData.useAttr;
            if (!CodeUtil.isNullOrZero(useAttr)) {
                return true;
            }
        }
        return false;
    }
    static getUnitDataByUnit(unit: UnitModel) {
        const strId = unit.strId;
        const unitData = DataRouter.getUnitDataByUnitId(strId);
        return unitData;
    }
    static getDataModelByWeight (player: PlayerModel, datas: WeightIDData[], num: number): WeightIDData[] {
        let sumWeight = 0;
        const caluArr: { id: string, weight: number, probability: number }[] = [];
        for (let i = 0; i < datas.length; i++) {
            const data = JSON.parse(JSON.stringify(datas[i]));
            const weight = data.weight;
            sumWeight = sumWeight + weight;
            caluArr.push(data);
        }
        let sumProbability = 0;
        for (let i = 0; i < caluArr.length; i++) {
            const ret = caluArr[i];
            const probability = ret.weight * 100 / sumWeight;
            ret.probability = probability;
            sumProbability = sumProbability + probability;
        }
        // 几率从小到大排序
        caluArr?.sort(
            (a: { id: string; weight: number; probability: number; }, b: { id: string; weight: number; probability: number; }) => {
                if (a.probability > b.probability) {
                    return 1
                }
                return 0;
            }
        )
        let rets: WeightIDData[] = [];
        for (let numIndex = num - 1; numIndex >= 0; numIndex--) {
            let random = player.getRandomReal(0, sumProbability * 100) / 100;
            // let random = 1;
            let tempSumProbability = sumProbability;
            const len = caluArr.length;
            if (len >= 1) {
            } else {
                break;
            }
            for (let i = caluArr.length - 1; i >= 0 ; i --) {
                const ret = caluArr[i];
                const probability = ret.probability;
                tempSumProbability = tempSumProbability - probability;
                if (tempSumProbability <= random) {
                    rets.push(ret);
                    caluArr.splice(i, 1);
                    sumProbability = sumProbability - probability;
                    break;
                }
            }
        }
        return rets;
    }

    static checkIsPet(targetUnit: UnitModel) {
        const unitId = targetUnit.strId;
        const unitData = DataRouter.getUnitDataByUnitId(unitId);
        const type = unitData && unitData.unit_type;
        if (type === UnitType.pet) {
            return true
        } else {
            return false;
        }
    }


    static getPetDataByCatchId(unitId: string) {
        const petDatas = DataRouter.getPetDatas();
        for (let i = 0; i < petDatas.length; i++) {
            const petData = petDatas[i];
            const catchId = petData.catch_id;
            if (catchId === unitId) {
                return petData;
            }
        }
    }

    static getPetDataByGetId(unitId: string) {
        const petDatas = DataRouter.getPetDatas();
        for (let i = 0; i < petDatas.length; i++) {
            const petData = petDatas[i];
            const getIds = petData.get_pet;
            const getIdArr = CodeUtil.getArrBySplit(getIds);
            for (let j = 0; j < getIdArr.length; j++) {
                const getId = getIdArr[j];
                if (getId === unitId) {
                    return petData;
                }
            }
        }
    }

    static getCombinationDataByName(combinationName: string): CombinationData[] {
        let ret: CombinationData[] = [];
        const combinationDatas = DataRouter.getCombinationDatas();
        for (let i = 0; i < combinationDatas.length; i++) {
            const tempData = combinationDatas[i];
            const tempName = tempData.name;
            if (tempName === combinationName) {
                ret.push(tempData)
            }
        }
        return ret;
    }

    // static equalCombinationDataLen(combinationId1: string, combinationId2: string): 1 | 0 | -1 {
    //     const combinationData1 = DataRouter.getCombinationDataByCombinationId(combinationId1);
    //     const combinationData2 = DataRouter.getCombinationDataByCombinationId(combinationId2);
    //     if (combinationData1 && combinationData2) {
    //         const materials1 = combinationData1.material_id;
    //         const materials1Arr = CodeUtil.getArrBySplit(materials1);
    //         const materials2 = combinationData2.material_id;
    //         const materials2Arr = CodeUtil.getArrBySplit(materials2);
    //
    //         if (materials1Arr.length > materials2Arr.length) {
    //             return 1
    //         } else if (materials1Arr.length === materials2Arr.length) {
    //             return 0
    //         } else if (materials1Arr.length < materials2Arr.length) {
    //             return -1
    //         }
    //     } else if (combinationData1) {
    //         return 1
    //     } else if (combinationData2) {
    //         return -1
    //     }
    // }
    static getLvByHandBookExp(currentExp: number, handBookData: HandBookData): { lv: number, exp: number, maxExp: number } {
        if (handBookData) {
        } else {
            return { lv: 0, exp: 0, maxExp: 0 }
        }
        const exps = handBookData.atlas_exp;
        let lv = 0;
        let maxExp = 10;
        const expArr = CodeUtil.getArrBySplit(exps);
        for (let i = 0; i < expArr.length; i ++) {
            const exp = DataRouterUtil.getNumByArr(expArr, i);
            const tempExp = currentExp - exp;
            if (tempExp >= 0) {
                lv = lv + 1;
                if (i === (expArr.length - 1)) {
                    currentExp = exp;
                    maxExp = exp
                    break;
                }
                // currentExp = tempExp;
            } else {
                maxExp = exp
                break;
            }
        }
        return { lv: lv, exp: currentExp, maxExp }
    }
    static getHandBookMaxExp(handBookData: HandBookData) {
        if (handBookData) {
        } else {
            return 0
        }
        const exps = handBookData.atlas_exp;
        if (exps) {
        } else {
            Logger.toastError('图鉴没有设置每级需要的经验');
            return 0;
        }
        const expArr = CodeUtil.getArrBySplit(exps);
        const maxExp = DataRouterUtil.getNumByArr(expArr, expArr.length - 1);
        if (maxExp) {
            return maxExp;
        }
        return 0
    }

    static getMaxExpByLv(lv: number) {
        const initExp = Configer.getConfig(ConfigKey.initExp);
        const expBase = Configer.getConfig(ConfigKey.expBase);
        return lv * expBase;
    }

    static getLvByExp (exp: number) {
        if (CodeUtil.isNullOrZero(exp)) {
            return 1;
        }
        const expBase = Configer.getConfig(ConfigKey.expBase);
        let lv = 1;
        let tempLv = exp / expBase;
        tempLv = Math.ceil(tempLv);
        if (tempLv > lv) {
            lv = tempLv;
        }
        return lv;
    }

    static getDifficultData(index: number): DifficultData {
        const difficultDatas = DataRouter.getDifficultDatas();
        return difficultDatas[index]
    }
    static getUnitDataByUnitStr(unitStr: string) {
        const unitUseFamily = Configer.getConfig(ConfigKey.unitUseFamily);
        let unitData: UnitData;
        if (!CodeUtil.isNullOrZero(unitUseFamily)) {
            const firstUnitId = DataRouterUtil.getFirstUnitIdByFamilyId(unitStr);
            unitData = DataRouter.getUnitDataByUnitId(firstUnitId);
        } else {
            unitData = DataRouter.getUnitDataByUnitId(unitStr);
        }
        return unitData;
    }
    static getUnitStr(unit: UnitModel) {
        const strId = unit.strId;
        const useFamily = Configer.getConfig(ConfigKey.unitUseFamily);
        if (useFamily > 0) {
            const unitData = DataRouter.getUnitDataByUnitId(strId);
            if (unitData?.family_tpye) {
                return unitData.family_tpye;
            }
        }
        return strId;
    }
    static getItemStr(strId: string) {
        const useFamily = Configer.getConfig(ConfigKey.itemUseFamily);
        if (useFamily > 0) {
            const itemData = DataRouter.getItemDataByItemId(strId);
            if (itemData) {
                return itemData.family_tpye;
            }
        }
        return strId;
    }
    static getUnitStrByUnitId(strId: string) {
        const useFamily = Configer.getConfig(ConfigKey.unitUseFamily);
        if (useFamily > 0) {
            const unitData = DataRouter.getUnitDataByUnitId(strId);
            if (unitData) {
                return unitData.family_tpye;
            }
        }
        return strId;
    }

    static getAttrByAttrInterface(attrId: string, num: number): Attrs {
        const unitAttr = new UnitAttribute();
        // const playerAttr = new PlayerAttribute();
        const ret = { unitAttr, playerAttr: undefined };

        if (attrId) {
        } else {
            return ret;
        }

        const attrData = DataRouter.getAttrDataByAttrId(attrId);

        if (attrData) {
        } else {
            return ret;
        }

        const bAll = (!CodeUtil.isNullOrZero(attrData.bAll));

        if (bAll) {
            const playerAttr = new PlayerAttribute();
            const playerKeys = Object.keys(playerAttr);
            for (let i = 0; i < playerKeys.length; i ++) {
                const key = playerKeys[i];
                const value = attrData[AttributeEnum[key]];
                if (!CodeUtil.isNullOrZero(value)) {
                    playerAttr[key] = value * num;
                } else {
                    playerAttr[key] = 0;
                }
            }
            ret.playerAttr = playerAttr;
        } else {
            const unitKeys = Object.keys(unitAttr);
            for (let i = 0; i < unitKeys.length; i ++) {
                const key = unitKeys[i];
                const value = attrData[AttributeEnum[key]];
                if (!CodeUtil.isNullOrZero(value)) {
                    unitAttr[key] = value * num;
                } else {
                    unitAttr[key] = 0;
                }
            }
        }
        return ret;
    }

    static getCombinationInfoStr(combinationId: string, ret: CombitionRet, ids: {[key: string]: number}, getNameFun: (id: string) => string, useLadder: number) {
        let retStr = '';
        const combinationData = DataRouter.getCombinationDataByCombinationId(combinationId);
        const materialIds = combinationData?.material_id;
        const materialIdArr = CodeUtil.getArrBySplit(materialIds);

        const name = combinationData?.name;
        if (name) {
            retStr = retStr + `${name}`;
        }

        let membetStr = '';
        let memberNum = 0;

        for (let i = 0; i < materialIdArr.length; i ++) {
            const id = materialIdArr[i];
            const num = ids[id]

            let unitName = getNameFun(id);

            if (num && num >= 0) {
                memberNum = memberNum + 1;
            } else {
                unitName = CodeUtil.getColorStr(ColorStr.gray, unitName);
            }

            membetStr = membetStr + unitName + '\n';
        }

        retStr = retStr + ` (${memberNum}/${materialIdArr.length})\n`

        retStr = retStr + membetStr + '\n';

        if (combinationData?.desc) {
            const descArr = CodeUtil.getArrBySplit(combinationData?.desc);
            const numArr = CodeUtil.getArrBySplit(combinationData?.material_num);
            let successNum = -1;
            if (ret) {
                successNum = ret?.successNum;
            }
            let bNull = true;
            let descStr = '';

            if (!CodeUtil.isNullOrZero(useLadder)) {
                for (let i = 0; i < numArr.length; i++) {
                    const num = DataRouterUtil.getNumByArr(numArr, i);
                    if (descArr[i] && num) {
                        descArr[i] = `(${num})${descArr[i]}`
                        if (num <= successNum && bNull) {
                            descArr[i] = CodeUtil.getColorStr(ColorStr.white, descArr[i])
                        } else {
                            descArr[i] = CodeUtil.getColorStr(ColorStr.gray, descArr[i])
                        }
                    }
                }
            } else {
                for (let i = numArr.length - 1; i >= 0; i--) {
                    const num = DataRouterUtil.getNumByArr(numArr, i);
                    if (descArr[i] && num) {
                        descArr[i] = `(${num})${descArr[i]}`
                        if (num <= successNum && bNull) {
                            bNull = false;
                            descArr[i] = CodeUtil.getColorStr(ColorStr.white, descArr[i])
                        } else {
                            descArr[i] = CodeUtil.getColorStr(ColorStr.gray, descArr[i])
                        }
                    }
                }
            }

            descStr = descArr.join('\n');

            // if (ret?.successNum === 0) {
            //     descStr = CodeUtil.getColorStr(ColorStr.gray, descStr);
            // }
            retStr = retStr + descStr;
        }

        return retStr;
    }

    // 返回羁绊id与用于显示的结果
    static checkToCombitionByMaterialInfos(materialInfos: MaterialInfo[], materialDatas: CombinationData[], useLadder: boolean) {
        // const checkMixRets: { mixId: string, funs: (() => void)[] }[] = [];
        const checkMixRets: { [mixId: string]: CombitionRet } = {};
        if (materialDatas && materialDatas.length > 0) {
            const arrs:  { id: string,  attrs: string[], effects: string[], items: string[], nums: string[], completeNums: string[]}[] = [];
            // 预先装载所有合成表信息
            for (let i = 0; i < materialDatas.length; i++) {
                const mixData = materialDatas[i];
                const id = mixData.id;
                const itemStrs = mixData.material_id;
                let itemArr = CodeUtil.getArrBySplit(itemStrs);

                const attrIds = mixData.attrId;
                let attrId = CodeUtil.getArrBySplit(attrIds);

                const effects = mixData.effects;
                let effect = CodeUtil.getArrBySplit(effects);

                const numStrs = mixData.material_num;
                const numArr = CodeUtil.getArrBySplit(numStrs);
                const completeNums = JSON.parse(JSON.stringify(numArr));
                const element: { id: string,  attrs: string[], effects: string[], items: string[], nums: string[], completeNums: string[] } = {  id, attrs: attrId, effects: effect , items: itemArr, nums: numArr, completeNums: completeNums };
                arrs.push(element);
            }

            // 遍历当前物品组，判断物品组中物品是否符合合成条件
            for (let itemIndex = 0; itemIndex < materialInfos.length; itemIndex++) {
                const materialInfo = materialInfos[itemIndex];
                const currentId = materialInfo.id;

                for (let materialIndex = 0; materialIndex < arrs.length; materialIndex++) {
                    const data = arrs[materialIndex];
                    const mixId = data.id;
                    const items = data.items;
                    const nums = data.nums;
                    const completeNums = data.completeNums;
                    const effects = data.effects;
                    const attrs = data.attrs;

                    const index = items.indexOf(currentId);
                    if (index >= 0) {
                        let ret: CombitionRet;
                        if (checkMixRets[mixId]) {
                        } else {
                            checkMixRets[mixId] = { attrs: undefined, effects: [], successNum: 0, currentNum: 0 }
                        }
                        ret = checkMixRets[mixId];

                        ret.currentNum = ret.currentNum + 1;

                        items.splice(index, 1);
                        for (let numIndex = nums.length - 1; numIndex >= 0; numIndex--) {
                            const num = DataRouterUtil.getNumByArr(nums, numIndex);
                            const tempNum = num - 1;

                            if (num === 0) {
                                break;
                            } else if (tempNum === 0) {
                                // nums.splice(numIndex, 1);
                                let effectId: string[], attrId: string[];
                                if (!CodeUtil.isNullOrZero(useLadder)) {
                                    effectId = effects.slice(0, numIndex + 1);
                                    attrId = attrs.slice(0, numIndex + 1);
                                } else {
                                    effectId = [effects[numIndex]];
                                    attrId = [attrs[numIndex]];
                                }

                                // Logger.toastError(`${JSON.stringify(completeNums)}  ${numIndex}`)

                                ret.successNum = DataRouterUtil.getNumByArr(completeNums, numIndex);

                                if (attrId.length > 0) {
                                    let tempAttrs: Attrs = { unitAttr: new UnitAttribute(), playerAttr: undefined };
                                    for (let attrIndex = 0; attrIndex < attrId.length; attrIndex ++) {
                                        const tempAttrId = attrId[attrIndex];
                                        const tempAttr = DataRouterUtil.getAttrByAttrInterface(tempAttrId, 1);
                                        tempAttrs = Util.sumAttributes(tempAttrs, tempAttr, CaluType.add);
                                    }
                                    ret.attrs = tempAttrs;
                                }
                                if (effectId.length > 0) {
                                    ret.effects = effectId;
                                }
                                nums[numIndex] = tempNum + '';
                                break;
                            } else {
                                nums[numIndex] = tempNum + '';
                            }
                        }
                    }
                }
                // const keys = Object.keys(checkMixRets);
                // if (keys.length > 0) {
                //     break;
                // }
            }
        }
        return checkMixRets;
    }

    static bindItemBlong(item: ItemModel, player: PlayerModel) {
        const bindItemBlong = Configer.getConfig(ConfigKey.bindItemBlong);
        if (bindItemBlong > 0) {
            item.data[ItemDataKey.ownerId] = player.playerId
        }
    }

    static addNewAffixToItem(item: ItemModel) {
        if (item) {
        } else {
            return;
        }
        const strId = item.strId;
        const itemData = DataRouter.getItemDataByItemId(strId);
        if (itemData) {
            const affix_num = itemData.affix_num;
            if (!CodeUtil.isNullOrZero(affix_num)) {
                const affixArr: string[] = DataRouterUtil.getAffixByGroupId(itemData.affix_group, affix_num);
                if (affixArr && affixArr?.length && affixArr?.length > 0) {
                    item.data[ItemDataKey.itemAffix] = affixArr.join(',');
                }
                return affixArr;
            }
            return [];
        }
    }

    static getNumByArr(arr: string[], index: number): number {
        const ele = arr[index] as unknown;
        const num: number = MathUtil.toNumber(ele);
        return num;
    }

    
    static getAttrDes(attribute: UnitAttribute) {
        if (attribute) {
            let ret = '';
            const attrSetting = Configer.getConfig(ConfigKey.attrSetting);
            const keys = Object.keys(attribute);
            for (let i = 0; i < keys.length; i++) {
                const key = keys[i];
                const value = attribute[key];
                if (!CodeUtil.isNullOrZero(value)) {
                    const attrBody = attrSetting[key] as AttrSetting;
                    if (attrBody) {
                        ret = ret + `${attrBody.name} +${MathUtil.floor(value)}${attrBody.suffix}\n`
                    }
                }
            }
            return ret;
        }
        return '';
    }
    static getItemInfoDes(itemModel: ItemInfo, lv: number, combinationUIInfo: CombinationUIInfo): { title: string, subTitle: string, des: string } {
        const template = DataRouter.getItemDataByItemId(itemModel.strId);
        if (template) {
            let name = template.Name;
            let des = template.Ubertip ? template.Ubertip : '';
            const useLadder = Configer.getConfig(ConfigKey.itemUseLadder)
            let subTitle = '';
            if (!CodeUtil.isNullOrZero(template?.wear_level)) {
                subTitle = `Lv: ${template.wear_level}\n`
                if (lv >= template.wear_level) {
                    subTitle = CodeUtil.getColorStr(ColorStr.green, subTitle);
                } else {
                    subTitle = CodeUtil.getColorStr(ColorStr.red, subTitle);
                }
            }
            let position = template.position;
            const equipAdapts = Configer.getUIConfig(UIConfigKey.EquipAdapt);
            if (!CodeUtil.isNullOrZero(position)) {
                const equipAdapt: PositionConfig = equipAdapts[position];
                subTitle = subTitle + `部位: ${equipAdapt.name}\n`
            }
            const currentNum = itemModel.num > 0 ? itemModel.num : 1
            const goldNum = MathUtil.floor(template.goldcost / 2) * currentNum;
            let sellStr = template.goldcost ? `售价: ${goldNum}金币` : `售价: 0金币`;
            sellStr = CodeUtil.getColorStr(ColorStr.gold, sellStr);
            subTitle = `${subTitle}${sellStr}`

            const forgLv = itemModel.lv;
            const forgAddRadix = Configer.getConfig(ConfigKey.forgAddRadix);
            const num = (1 + forgAddRadix * forgLv)

            if (!CodeUtil.isNullOrZero(forgLv)) {
                name = `${name}(+${forgLv})`;
            }
    
            const attr = DataRouterUtil.getAttrByAttrInterface(template.attrId, num);
            const attrDes = DataRouterUtil.getAttrDes(attr.unitAttr);

            if (!CodeUtil.isNullOrZero(attrDes)) {
                des = des + `${attrDes}`;
            }

            let affixRetStr = '';
            const affixStr = itemModel.affixs;
            const affixArr = CodeUtil.getArrBySplit(affixStr);
            for (let i = 0; i < affixArr.length; i++) {
                const affixId = affixArr[i];
                const affixData = DataRouter.getAffixDatasByAffixID(affixId);
                const affixUbertip = affixData?.Ubertip;

                if (affixData) {
                    if (!CodeUtil.isNullOrZero(affixUbertip)) {
                        affixRetStr = affixRetStr + `${affixUbertip}\n`;
                    }

                    const affixAttr = DataRouterUtil.getAttrByAttrInterface(affixData.attrId, 1);
                    const affixAttrDes = DataRouterUtil.getAttrDes(affixAttr.unitAttr);

                    if (!CodeUtil.isNullOrZero(affixAttrDes)) {
                        affixRetStr = affixRetStr + affixAttrDes;
                    }

                    let affixName = affixData.Name;
                    affixName = CodeUtil.getColorStr(ColorStr.green, `[${affixName}]`)
                    if (!CodeUtil.isNullOrZero(affixName)) {
                        name = `${affixName}${name}`
                    }
                }
            }

            affixRetStr = CodeUtil.getColorStr(ColorStr.lightblue, affixRetStr);
            des = `${des}${affixRetStr}`;

            // 套装描述
            const itemUseFamily = Configer.getConfig(ConfigKey.itemUseFamily);
            const getNameFun = (id: string) => {
                let itemName;
                if (itemUseFamily > 0) {
                    itemName = id;
                } else {
                    const itemData = DataRouter.getItemDataByItemId(id);
                    itemName = itemData?.Name ? itemData.Name : '';
                }
                return itemName;
            }

            let combinationStr = '';
            const combinationIds = combinationUIInfo.combinationIds;
            const ids = combinationUIInfo.ids;
            const keys = Object.keys(combinationIds);
            for (let i = 0; i < keys.length; i++) {
                const key = keys[i];
                const combinationRet = combinationIds[key];
                combinationStr = combinationStr + DataRouterUtil.getCombinationInfoStr(key, combinationRet, ids, getNameFun, useLadder) + '\n';
            }
            des = `${des}\n${combinationStr}`;

            return { title: name, subTitle, des };
        }
        return { title: '', subTitle: '', des: '' };
    }
}